import React, { useState } from 'react';
import difference from 'lodash/difference';
import { history } from 'umi';
import {
    formatMessage,
    FormattedMessage,
    FormattedHTMLMessage
} from 'umi';
import { connect } from 'umi';
import {
    Form,
    Input,
    Button,
    Steps,
    Row,
    Modal,
    Col,
    Icon,
    Popover
} from 'antd';
import withClearState from '@/utils/withClearState';
// import { getStrLen } from '@/utils/utils';
import styles from './ForgotPassword.less';

const { Step } = Steps;
const FormItem = Form.Item;

const ForgotPassword = ({
    form,
    checkUserEmail,
    resetPassword,
    dispatch,
    forgotPassword
}) => {
    const { getFieldDecorator } = form;
    const { email, employeeName, key: verificationKey } = forgotPassword;
    const [modalVisible, setModalVisible] = useState(false);
    const [tipVisible, setTipVisible] = useState(false); // 控制密码的popover提示
    const [nameTipVisible, setNameTipVisible] = useState(false); // 控制用户名的popover提示
    const [initSend, setInitSend] = useState(true);
    const [step, setStep] = useState(0);
    const [disableSend, setDisableSend] = useState(false);
    const [countDown, setCountDown] = useState(0);
    const [initTimer, setInitTimer] = useState(false); // 控制倒计时不受组件update影响

    const formItemLayout = {
        labelCol: {
            xs: { span: 24 },
            sm: { span: step === 0 ? 8 : 4 }
        },
        wrapperCol: {
            xs: { span: 24 },
            sm: { span: 12 }
        }
    };

    const tailFormItemLayout = {
        wrapperCol: {
            xs: {
                span: 24,
                offset: 0
            },
            sm: {
                span: 12,
                offset: 8
            }
        }
    };

    let interval = null;
    const onGetCode = () => {
        if (initTimer) return;
        setInitTimer(true);
        setDisableSend(true);
        let count = 60;
        interval = setInterval(() => {
            count -= 1;
            setCountDown(count);
            if (count === 0) {
                clearInterval(interval);
                setDisableSend(false);
                setInitTimer(false);
            }
        }, 1000);
    };

    const dispatchGetVerificationCode = () => {
        const payload = {
            type: 2,
            loginName: email || form.getFieldValue('userEmail'), // 第一次callback的时候还没有复制email
            organizeType: 1
        };
        dispatch({
            type: 'forgotPassword/getVerificationCode',
            payload,
            callback() {
                onGetCode();
                if (initSend) {
                    setModalVisible(true);
                    setInitSend(false);
                }
            }
        });
    };

    const dispatchCheckUserEmail = () => {
        form.validateFields(
            ['userName', 'userEmail'],
            { force: true },
            (err, values) => {
                if (!err) {
                    const payload = {
                        employeeName: values.userName,
                        email: values.userEmail
                    };
                    dispatch({
                        type: 'forgotPassword/checkUserEmail',
                        payload,
                        callback() {
                            dispatchGetVerificationCode();
                            setStep(1);
                        }
                    });
                }
            }
        );
    };

    const dispatchResetPassword = () => {
        form.validateFields(
            ['newPassword', 'confirmPassword', 'verificationCode'],
            { force: true },
            (err, values) => {
                if (!err) {
                    const payload = {
                        newPassword: values.newPassword,
                        confirmNewPassword: values.confirmPassword,
                        verificationKey,
                        verificationValue: values.verificationCode,
                        loginName: email,
                        organizeType: 1
                    };
                    dispatch({
                        type: 'forgotPassword/resetPassword',
                        payload,
                        callback() {
                            setStep(2);
                        }
                    });
                }
            }
        );
    };

    const handleSubmit = e => {
        e.preventDefault();

        const handleMap = {
            0: dispatchCheckUserEmail,
            1: dispatchResetPassword
        };
        handleMap[step]();
    };

    const submitLoading = () => {
        const submitMap = {
            0: checkUserEmail,
            1: resetPassword
        };
        return submitMap[step];
    };

    const getPasswordStatus = () => {
        const value = form.getFieldValue('newPassword');
        const checked = [];
        if (!value) return [];
        if (value.length >= 8 && value.length <= 20) {
            checked.push('1');
        }
        if (/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$/.test(value)) {
            checked.push('2');
        }
        return checked;
    };

    const getUserNameStatus = () => {
        const value = form.getFieldValue('userName');
        const checked = [];
        if (!value) return [];
        // const len = getStrLen(value);
        const len = value?.length || 0;
        if (len >= 2 && len <= 50) {
            checked.push('1');
        }
        return checked;
    };

    const renderStatusClass = ary => ary.map(item => styles[`step${item}`]).join(' ');

    const validatePassword = (rule, value, callback) => {
        if (tipVisible) callback(); // focus时不显示
        const statusAry = getPasswordStatus();
        const errorAry = difference(['1', '2'], statusAry);
        if (!value) {
            callback(formatMessage({ id: 'form.newPassword.placeholder' }));
        } else if (errorAry.length) {
            const errorStr = errorAry
                .map(item =>
                    formatMessage({
                        id: `form.passwordRuleStep${item}.validate`
                    })
                )
                .join('，');
            callback(errorStr);
        } else {
            callback();
        }
        form.validateFields(['confirmPassword'], { force: true });
    };

    const validateConfirmPassword = (rule, value, callback) => {
        if (!value) {
            callback(formatMessage({ id: 'form.confirmPassword.placeholder' }));
        } else if (value !== form.getFieldValue('newPassword')) {
            callback(formatMessage({ id: 'validation.password.twice' }));
        } else {
            callback();
        }
    };

    const validateUserName = (rule, value, callback) => {
        const statusAry = getUserNameStatus();
        const errorAry = difference(['1'], statusAry);
        if (!value) {
            callback(formatMessage({ id: 'form.staffName.placeholder' }));
        } else if (errorAry.length) {
            const errorStr = errorAry
                .map(item =>
                    formatMessage({
                        id: `form.staffNameRuleStep${item}.validate`
                    })
                )
                .join('，');
            callback(errorStr);
        } else {
            callback();
        }
    };

    const renderLayout = () => {
        const layoutMap = {
            0: (
                <Row gutter={24}>
                    <FormItem
                        label={formatMessage({ id: 'form.staffName.label' })}
                    >
                        <Popover
                            getPopupContainer={node => {
                                if (node && node.parentNode) {
                                    return node.parentNode;
                                }
                                return node;
                            }}
                            content={
                                <div
                                    style={{ padding: 0 }}
                                    className={`${
                                        styles.validatePassword
                                    } ${renderStatusClass(
                                        getUserNameStatus()
                                    )}`}
                                >
                                    <div>
                                        <Icon
                                            type="check-circle"
                                            theme="filled"
                                        />
                                        <FormattedMessage id="form.staffNameRuleStep1.validate" />
                                    </div>
                                </div>
                            }
                            placement="right"
                            visible={nameTipVisible}
                        >
                            {getFieldDecorator('userName', {
                                getValueFromEvent(e) {
                                    if (!e || !e.target) {
                                        return e;
                                    }
                                    const { target } = e;
                                    return target.value.trim();
                                },
                                rules: [
                                    {
                                        required: true,
                                        validator: validateUserName
                                    }
                                ]
                            })(
                                <Input
                                    placeholder={formatMessage({
                                        id: 'form.staffName.placeholder'
                                    })}
                                    onFocus={() => setNameTipVisible(true)}
                                    onBlur={() => setNameTipVisible(false)}
                                    autocomplete="off"
                                />
                            )}
                        </Popover>
                    </FormItem>
                    <FormItem
                        label={formatMessage({ id: 'form.staffEmail.label' })}
                    >
                        {getFieldDecorator('userEmail', {
                            rules: [
                                {
                                    required: true,
                                    message: formatMessage({
                                        id: 'form.staffEmail.placeholder'
                                    })
                                },
                                {
                                    type: 'email',
                                    message: formatMessage({
                                        id: 'validation.email.wrong-format'
                                    })
                                }
                            ]
                        })(
                            <Input
                                placeholder={formatMessage({
                                    id: 'form.staffEmail.placeholder'
                                })}
                                autocomplete="off"
                            />
                        )}
                    </FormItem>
                    <FormItem {...tailFormItemLayout}>
                        <Button
                            style={{ marginRight: 16 }}
                            onClick={() => {
                                history.push('/user/login');
                            }}
                        >
                            <FormattedMessage id="btn.form.cancel" />
                        </Button>
                        <Button
                            loading={submitLoading()}
                            type="primary"
                            htmlType="submit"
                        >
                            <FormattedMessage id="btn.form.next" />
                        </Button>
                    </FormItem>
                </Row>
            ),
            1: (
                <Row gutter={24}>
                    <Row>
                        <FormItem
                            label={formatMessage({
                                id: 'form.verification.label'
                            })}
                            extra={
                                <span className={styles.inputExtra}>
                                    <Icon type="check-circle" theme="filled" />
                                    <FormattedMessage id="app.reset-password.tip-msg"></FormattedMessage>
                                </span>
                            }
                        >
                            <Row gutter={8}>
                                <Col span={12}>
                                    {getFieldDecorator('verificationCode', {
                                        rules: [
                                            {
                                                required: true,
                                                message: formatMessage({
                                                    id:
                                                        'form.verification.placeholder'
                                                })
                                            }
                                        ]
                                    })(
                                        <Input
                                            placeholder={formatMessage({
                                                id:
                                                    'form.verification.placeholder'
                                            })}
                                            autocomplete="off"
                                        />
                                    )}
                                </Col>
                                <Col span={12}>
                                    <Button
                                        onClick={() =>
                                            dispatchGetVerificationCode()
                                        }
                                        disabled={disableSend}
                                    >
                                        <FormattedMessage id="btn.form.resendCode" />
                                        {countDown > 0 && `(${countDown})`}
                                    </Button>
                                </Col>
                            </Row>
                        </FormItem>
                        <FormItem
                            label={formatMessage({
                                id: 'form.newPassword.label'
                            })}
                        >
                            <Popover
                                getPopupContainer={node => {
                                    if (node && node.parentNode) {
                                        return node.parentNode;
                                    }
                                    return node;
                                }}
                                content={
                                    <div
                                        style={{ padding: 0 }}
                                        className={`${
                                            styles.validatePassword
                                        } ${renderStatusClass(
                                            getPasswordStatus()
                                        )}`}
                                    >
                                        <div>
                                            <Icon
                                                type="check-circle"
                                                theme="filled"
                                            />
                                            <FormattedMessage id="form.passwordRuleStep1.validate" />
                                        </div>
                                        <div>
                                            <Icon
                                                type="check-circle"
                                                theme="filled"
                                            />
                                            <FormattedMessage id="form.passwordRuleStep2.validate" />
                                        </div>
                                    </div>
                                }
                                placement="right"
                                visible={tipVisible}
                            >
                                {getFieldDecorator('newPassword', {
                                    validateTrigger: ['onChange', 'onFocus'],
                                    rules: [
                                        {
                                            required: true,
                                            validator: validatePassword
                                        }
                                    ]
                                })(
                                    <Input.Password
                                        placeholder={formatMessage({
                                            id: 'form.newPassword.placeholder'
                                        })}
                                        onFocus={() => setTipVisible(true)}
                                        onBlur={() => setTipVisible(false)}
                                        autocomplete="off"
                                    />
                                )}
                            </Popover>
                        </FormItem>
                        <FormItem
                            label={formatMessage({
                                id: 'form.confirmPassword.label'
                            })}
                        >
                            {getFieldDecorator('confirmPassword', {
                                rules: [
                                    {
                                        required: true,
                                        validator: validateConfirmPassword
                                    }
                                ]
                            })(
                                <Input.Password
                                    placeholder={formatMessage({
                                        id: 'form.confirmPassword.placeholder'
                                    })}
                                    autocomplete="off"
                                />
                            )}
                        </FormItem>
                        <FormItem {...tailFormItemLayout}>
                            <Button
                                style={{ marginRight: 16 }}
                                onClick={() => setStep(0)}
                            >
                                <FormattedMessage id="btn.form.prev" />
                            </Button>
                            <Button
                                loading={submitLoading()}
                                type="primary"
                                htmlType="submit"
                            >
                                <FormattedMessage id="btn.form.confirm" />
                            </Button>
                        </FormItem>
                    </Row>
                </Row>
            ),
            2: (
                <div className={styles.resetSuccess}>
                    <Icon
                        type="check-circle"
                        theme="filled"
                        style={{
                            fontSize: 72,
                            marginTop: 20
                        }}
                    />
                    <div style={{ fontSize: 24, marginTop: 24 }}>
                        <FormattedMessage id="app.reset-password.success" />
                    </div>
                    <div className={styles.info} style={{ marginTop: 16 }}>
                        <FormattedMessage id="app.reset-password.success-tip" />
                    </div>
                    <Button
                        type="primary"
                        style={{ marginTop: 32 }}
                        onClick={() => {
                            history.push('/user/login');
                        }}
                    >
                        <FormattedMessage id="app.reset-password.success-btn" />
                    </Button>
                </div>
            )
        };
        return layoutMap[step];
    };

    return (
        <div id="my__page" className={styles.main}>
            <Row type="flex" justify="center" className={styles.mainTitle}>
                <FormattedMessage id="app.reset-password.title" />
            </Row>
            <Steps current={step}>
                <Step
                    size="small"
                    title={formatMessage({
                        id: 'app.reset-password.step1'
                    })}
                />
                <Step
                    size="small"
                    title={formatMessage({
                        id: 'app.reset-password.step2'
                    })}
                />
                <Step
                    size="small"
                    title={formatMessage({
                        id: 'app.reset-password.step3'
                    })}
                />
            </Steps>
            <Form
                onSubmit={handleSubmit}
                {...formItemLayout}
                className={styles.form}
            >
                {renderLayout()}
            </Form>
            <Modal
                visible={modalVisible}
                centered
                title={formatMessage({
                    id: 'app.reset-password.title'
                })}
                onCancel={() => setModalVisible(false)}
                footer={[
                    <Button
                        key="confirm"
                        type="primary"
                        onClick={() => setModalVisible(false)}
                    >
                        <FormattedMessage id="btn.form.confirm" />
                    </Button>
                ]}
            >
                <div className={styles['confirm-msg']}>
                    <FormattedHTMLMessage
                        id="app.reset-password.confirm-msg"
                        values={{
                            user: employeeName,
                            email
                        }}
                    />
                </div>
            </Modal>
        </div>
    );
};

export default connect(({ loading, forgotPassword }) => ({
    forgotPassword,
    getVerificationCode: loading.effects['forgotPassword/getVerificationCode'],
    resetPassword: loading.effects['forgotPassword/resetPassword'],
    checkUserEmail: loading.effects['forgotPassword/checkUserEmail']
}))(Form.create()(withClearState('forgotPassword')(ForgotPassword)));
